home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / 80x0393.zip / LOADALL.TXT < prev    next >
Text File  |  1993-03-30  |  9KB  |  216 lines

  1. From: Mark Dixon
  2. Subj: LOADALL
  3. ________________________________________________________________________
  4.  
  5.  >    I know from past threads that LOADALL is an intruction available
  6.  > on 80x86 CPU's with a protected mode that is undocumented by  INTEL  
  7.  > but  was  used by Microsoft in their VDISK  program,  amoung  other  
  8.  > places.   I have rather  fragmentary  information  suggesting  that 
  9.  > there is "another"  LOADALL instruction  on 80386+  chips,  perhaps 
  10.  > only a BIOS emulation (?)  of the 286's LAOADALL.
  11.  
  12. Apparently, so my doc's tell me, the actual instruction is only  present 
  13. on 286 processors, but that 386+ processors have similar functions  that 
  14. allow  it to achive the same thing. So it's just a matter  of  detecting 
  15. 286/386 and using the appropriate routine....
  16.  
  17. Anyway, here's a few extracts from my doc's on loadall ;
  18.  
  19. Some uses for the Loadall instruction (just to get your mind going) :
  20. - getting  at  all  the memory in your machine at will, even  if  it  is
  21.   addressed above 1 megabyte, from real mode.
  22. - executing real-mode programs in ram above one megabyte.
  23. - installing a second operating-system-like program, or command  proces-
  24.   sor, or shell, in memory above 1 megabyte, and alternating between that
  25.   and DOS.
  26. - installing most of the guts of custom TSR's, shells, and  device-driv-
  27.   ers in ram above 1 megabyte (freeing up precious base memory), leaving 
  28.   in low memory only the stubs to call the code upstairs.
  29. - writing  very  large programs, which are "split", and  have  half  the
  30.   program  residing  in  the  low-down  640K, and the other half  up  in
  31.   extended memory, and running in either real or protected mode.
  32. - installing  large  protected-mode programs in extended  memory,  where
  33.   they will not conflict with, or crowd out DOS, and ping-ponging between
  34.   them and DOS.
  35. - switching to protected mode.
  36. - emulating  real mode from protected mode (tough, and full of  gotchas,
  37.   but still worth mentioning).
  38. - this is really off-the-wall, but possible: building automata that  use
  39.   Loadall  to  warp from state to state, sort of like a computer game of
  40.   Life, played in the twilight zone.
  41.  
  42.  
  43.                                    LOADALL
  44.  
  45. Okay, so what IS the Loadall instruction?
  46. Simple:
  47.  
  48. *** 0F 05 hex ***
  49.  
  50.    So  how does it work?  Well, I've already told you the  gist  of it:
  51. all CPU  registers  are loaded from a 51-word table of data that  starts  
  52. at  80:0h (absolute  24-bit  address 800h).  This address is  one  thing  
  53. that  cannot be changed or re-programmed. It's hard-wired into the chip, 
  54. and  that's  that.   And that's unfortunate,  because  all  versions  of 
  55. anybody's DOS earlier than version 3.3 use that area for critical system 
  56. code.
  57.  
  58.    Loadall  takes no operands, and is just a two-byte  instruction.  All 
  59. the "operands" for the instruction are obtained from the table at 80:0h.          
  60. Just  put "db 0Fh, 05" in your code stream, and watch the fun.  But  you 
  61. had better get that table right before you do, or else... (crash).
  62.  
  63.                 ** THE LOAD TABLE **
  64. -----------------------------------------------------------
  65. Address         Size            CPU register
  66.                 (words)
  67. -----------------------------------------------------------
  68.  
  69. 800             3       unused  (?? I don't believe it.)
  70. 806             1       MSW (Machine Status Word)
  71. 808             7       unused  (?? I don't believe it.)
  72. 816             1       TR (Task Register)
  73. 818             1       Flag Word
  74. 81A             1       IP (Instruction Pointer)
  75. 81C             1       LDT (Local Descriptor Table)
  76.  
  77. 81E             1       DS (Data Segment, or DS Selector)
  78. 820             1       SS (Stack Segment, or SS Selector)
  79. 822             1       CS (Code Segment, or CS Selector)
  80. 824             1       ES (Extra Segment, or CS Selector)
  81.  
  82. 826             1       DI (Destination Index)
  83. 828             1       SI (Source Index)
  84. 82A             1       BP (Base Pointer)
  85. 82C             1       SP (Stack Pointer)
  86.  
  87. 82E             1       BX (Data Register BX)
  88. 830             1       DX (Data Register BX)
  89. 832             1       CX (Data Register BX)
  90. 834             1       AX (Data Register BX)
  91.  
  92. 836             3       ES Descriptor Cache
  93. 83C             3       CS Descriptor Cache
  94. 842             3       SS Descriptor Cache
  95. 848             3       DS Descriptor Cache
  96.  
  97. 84E             3       GDTR
  98.                         (Global-Descriptor-Table Register)
  99.  
  100. 854             3       LDTDC
  101.                         (Local-Descriptor-Table Descriptor Cache)
  102.  
  103. 85A             3       IDTR
  104.                         (Interrupt-Descriptor-Table Register)
  105.  
  106. 860             3       TSSDC
  107.                         (Task-State-Segment Descriptor Cache)
  108.  
  109. total =         33h words == 102. bytes
  110.  
  111.  
  112.                   AND A PRETTY-TOGETHER DEFAULT TABLE
  113.  
  114.    So  here's  what  a  default  Loadall  table  looks  like.  Note that 
  115. "new_Reg_Buf"  doesn't label any data item that we really use; it's  the 
  116. name of the whole table.
  117.  
  118. ;    LOADALL Register Load Table for new values to be loaded
  119. ;    into registers by a Loadall.
  120.  
  121. new_Reg_Buf     dw      3 dup (0)       ; unused space
  122. newMSW          dw      0
  123. newDead         dw      7 dup (0)       ; unused space
  124. newTR           dw      0
  125. newFlagWord     dw      0
  126. newIP           dw      offset after_ldall      ; * may chng
  127. newLDT          dw      0
  128.  
  129. newDS           dw      0       ; *chng
  130. newSS           dw      0       ; *chng
  131. newCS           dw      0       ; *chng
  132. newES           dw      0       ; *chng
  133.  
  134. newDI           dw      0
  135. newSI           dw      0
  136. newBP           dw      0
  137. newSP           dw      0       ; *chng
  138.  
  139. newBX           dw      0
  140. newDX           dw      0
  141. newCX           dw      0
  142. newAX           dw      0
  143.  
  144. newESDC         dw      0,      9300h,  0FFFFh  ; *chng
  145. newCSDC         dw      0,      9300h,  0FFFFh  ; *chng
  146. newSSDC         dw      0,      9300h,  0FFFFh  ; *chng
  147. newDSDC         dw      0,      9300h,  0FFFFh  ; *chng
  148.  
  149. newGDTR         dw      D8A0h,  0FF00h, 88h     ; @ 0D8A:0 *n
  150. newLDTDC        dw      0,      0FF0Eh, 88h     ; @ E000:0
  151. newIDTR         dw      0,      0FF00h, 0FFFFh  ; @ 0000:0 *n
  152. newTSSDC        dw      4000h,  0FF0Eh, 800h    ; @ E400:0
  153.  
  154.  
  155.    Those  "*chng" comments mean that those items MUST be changed  by the 
  156. running  program before actually doing the Loadall. We cannot  correctly 
  157. default  them  in  the sources because the correct values  can  only  be 
  158. determined at runtime.
  159.  
  160.    The "*n" means that those values are not really in the default tables 
  161. in the sources: the running program uses the sgdt and sidt  instructions 
  162. to  get those values and then plugs them into those two  entries.   Just 
  163. letting you see what they will look like. You could have anything in the 
  164. original table there, because  the running program will over-write those 
  165. items with  correct values anyway.
  166.  
  167.    The "@ 0D8A:0" comments are just noting the addresses in those items, 
  168. in a more readable form.
  169.  
  170.  
  171.                        THE PROCEDURE FOR USING LOADALL
  172.                        (the ultra-safe, long procedure)
  173.  
  174. 1. Save  the  original machine state, so you have a state to  return to.  
  175. This  information  can be saved in a Loadall table, which  is  the  most 
  176. convenient form for later use.
  177.  
  178. 2. Disable interrupts.  Just in case.  We want a clean copy of area 80.
  179.  
  180. 3. Save  the 102-byte (33h words) block of data located at  80:0h.  Ver- 
  181. sions   of  DOS (both PC- and MS-) earlier than 3.3 use this  area   for 
  182. critical system code, and as of DOS 3.3, RamDrive.Sys, and Himem.Sys use 
  183. this area for their own Loadall tables.
  184.  
  185. 4. Re-enable  interrupts.   Let the clock ticks,  or  whatever, through, 
  186. while we do the following step.
  187.  
  188. 5. Set  up  the new Loadall table (new_reg_buf), which  defines  the new
  189. state we want to warp to.
  190.  
  191. 6. Disable Interrupts.
  192.  
  193. 7. Copy the new Loadall table to 80:0h.
  194.  
  195. 8. Execute a Loadall.
  196.  
  197. 9. Do  something  or other with your new machine state.   Read  or write 
  198. extended memory, run code upstairs, or whatever.
  199.  
  200. 10.  Copy the "old" Loadall table, containing the saved  machine  state, 
  201. down to 80:0.
  202.  
  203. 11.  Do   another  Loadall (Un-Loadall.)   This  restores  the  original 
  204. machine state.
  205.  
  206. 12. Copy the block of saved data back to 80:0h.
  207.  
  208. 13. Re-enable interrupts.
  209.  
  210. Well, I hope that helps a bit. This is just a small bit out of some  45k 
  211. doc  file I have on the subject. If you were really interested  (though, 
  212. this  is  most of the important stuff here) I could netmail  it  bit  by 
  213. bit...
  214.  
  215.   Mark.
  216.